﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using WebApplication.AppCode;
using BLL;
using Model;
using Newtonsoft.Json;
using System.Web.UI.HtmlControls;
using WebApplication.AppCode.View;
using System.Data.Entity;
using System.IO;

namespace WebApplication.Admin
{
    public partial class NodeDetails : BasePage
    {
        AppBLL bll = new AppBLL();
        protected NodeView model = null;
        protected string ModelJson = "null";
        protected string ContactsJson = "null";

        protected void Page_Load(object sender, EventArgs e)
        {
            if (IsPostBack)
            {
                model = JsonConvert.DeserializeObject<NodeView>(this.hidModelData.Value);
                ModelJson = JsonConvert.SerializeObject(model);
                if (model.Node.ID == Guid.Empty)
                {
                    Insert(model);
                }
                else
                {
                    Update(model);
                }
                CloseWindow();
                LoadData(model.Node.ID);
            }
            else if (Request["id"] != null)
            {
                Guid id;
                if (!Guid.TryParse(Request["id"], out id))
                {
                    AlertArgmentInvalid(); return;
                }
                LoadData(id);
            }
            else if (Request["pid"] != "")
            {
                this.hidProjectID.Value = Request["pid"];
                this.hidID.Value = Guid.Empty.ToString();
            }
        }

        private void Update(NodeView model)
        {
            var node = bll.DbContext.ProjectNodes.FirstOrDefault(x => x.ID == model.Node.ID);
            if (node == null)
            {
                AlertDataNotFound(); return;
            }
            node.Content = model.Node.Content;
            node.StandardDays = model.Node.StandardDays;
            node.Description = model.Node.Description;

            List<string> delRequired = new List<string>();
            var files = Request.Files;
            int i = 0;

            #region update in files
            model.InFiles.ForEach(x =>
            {
                if (x._state == "removed")
                {
                    delRequired.Add(x.FileURI);
                    var inFile = new NodeInFile { ID = x.ID };
                    bll.DbContext.NodeInFiles.Attach(inFile);
                    bll.DbContext.Entry(inFile).State = EntityState.Deleted;
                }
                else if (x._state == "added")
                {
                    x.ID = Guid.NewGuid();
                    x.NodeID = model.Node.ID;
                    x.File = files[i];
                    x.Filename = MapPath("~/Upload/" + x.ID + "_" + files[i].FileName);
                    bll.DbContext.NodeInFiles.Add(new NodeInFile
                    {
                        Department = x.Department,
                        FileURI = "/Upload/" + x.ID + "_" + files[i].FileName,
                        ID = Guid.NewGuid(),
                        Name = x.Name,
                        NodeID = model.Node.ID,
                        //ProjectNodeItem = model.Node
                    });
                    i++;
                }
            });
            #endregion
            #region update out files
            model.OutFiles.ForEach(x =>
            {
                if (x._state == "removed")
                {
                    delRequired.Add(x.FileURI);
                    var inFile = new NodeOutFile { ID = x.ID };
                    bll.DbContext.NodeOutFiles.Attach(inFile);
                    bll.DbContext.Entry(inFile).State = EntityState.Deleted;
                }
                else if (x._state == "added")
                {
                    x.ID = Guid.NewGuid();
                    x.NodeID = model.Node.ID;
                    x.File = files[i];
                    x.Filename = MapPath("~/Upload/" + Guid.NewGuid() + files[i].FileName);
                    bll.DbContext.NodeOutFiles.Add(new NodeOutFile
                    {
                        FileURI = "/Upload/" + x.ID + "_" + files[i].FileName,
                        ID = Guid.NewGuid(),
                        Name = x.Name,
                        NodeID = model.Node.ID,
                        //ProjectNodeItem = model.Node
                    });
                    i++;
                }
            });
            #endregion

            //update point and contacts
            model.PointContacts.ForEach(x =>
            {
                switch (x.Point._state)
                {
                    case "added":
                        #region add
                        Guid id = Guid.NewGuid();
                        x.Contacts.ForEach(f =>
                        {
                            f.NodePointID = id;
                            bll.DbContext.NodePointContactses.Add(new NodePointContacts { ContactID = f.ContactID, NodePointID = id });
                        });
                        bll.DbContext.ProjectNodePoints.Add(new ProjectNodePoint
                        {
                            ID = id,
                            Order = x.Point.Order,
                            PointID = x.Point.PointID,
                            ProjectNodeID = model.Node.ID,
                            Status = x.Point.Status,
                        });
                        #endregion
                        break;
                    case "modified":
                        var pnp = bll.DbContext.ProjectNodePoints.FirstOrDefault(w => w.ID == x.Point.ID);
                        pnp.Order = x.Point.Order;
                        x.Contacts.ForEach(f =>
                        {
                            switch (f._state)
                            {
                                case "added":
                                    bll.DbContext.NodePointContactses.Add(new NodePointContacts { ContactID = f.ContactID, NodePointID = x.Point.ID });
                                    break;
                                case "removed":
                                    var npc = new NodePointContacts { ContactID = f.ContactID, NodePointID = f.NodePointID };
                                    bll.DbContext.NodePointContactses.Attach(npc);
                                    bll.DbContext.Entry(npc).State = EntityState.Deleted;
                                    break;
                            }
                        });
                        break;
                    case "removed":
                        bll.DeletePoint(x.Point.ID);
                        break;
                }
            });

            try
            {
                bll.DbContext.SaveChanges();
                delRequired.ForEach(x =>
                {
                    File.Delete(Server.MapPath("~/" + x));
                });
                TimeAlertSuccess();
            }
            catch (Exception ex)
            {
                AlertOperateFailed("保存", ex);
            }
        }

        private void Insert(NodeView model)
        {
            model.Node.ID = Guid.NewGuid();
            model.Node.ProjectID = Guid.Parse(this.hidProjectID.Value);
            bll.DbContext.ProjectNodes.Add(model.Node);
            model.PointContacts.ForEach(x =>
            {
                Guid id = Guid.NewGuid();
                x.Contacts.ForEach(f =>
                {
                    f.NodePointID = id;
                    bll.DbContext.NodePointContactses.Add(new NodePointContacts { ContactID = f.ContactID, NodePointID = id });
                });
                bll.DbContext.ProjectNodePoints.Add(new ProjectNodePoint
                {
                    ID = id,
                    Order = x.Point.Order,
                    PointID = x.Point.PointID,
                    ProjectNodeID = model.Node.ID,
                    Status = x.Point.Status,
                });
            });

            var files = Request.Files;
            int i = 0;
            model.InFiles.ForEach(x =>
            {
                x.ID = Guid.NewGuid();
                x.NodeID = model.Node.ID;
                x.File = files[i];
                x.Filename = MapPath("~/Upload/" + x.ID + "_" + files[i].FileName);
                bll.DbContext.NodeInFiles.Add(new NodeInFile
                {
                    Department = x.Department,
                    FileURI = "/Upload/" + x.ID + "_" + files[i].FileName,
                    ID = Guid.NewGuid(),
                    Name = x.Name,
                    NodeID = model.Node.ID,
                    ProjectNodeItem = model.Node
                });
                i++;
            });
            model.OutFiles.ForEach(x =>
            {
                x.ID = Guid.NewGuid();
                x.NodeID = model.Node.ID;
                x.File = files[i];
                x.Filename = MapPath("~/Upload/" + Guid.NewGuid() + files[i].FileName);
                bll.DbContext.NodeOutFiles.Add(new NodeOutFile
                {
                    FileURI = "/Upload/" + x.ID + "_" + files[i].FileName,
                    ID = Guid.NewGuid(),
                    Name = x.Name,
                    NodeID = model.Node.ID,
                    ProjectNodeItem = model.Node
                });
                i++;
            });



            try
            {
                bll.DbContext.SaveChanges();
                model.InFiles.ForEach(x =>
                {
                    x.File.SaveAs(x.Filename);
                });
                model.OutFiles.ForEach(x =>
                {
                    x.File.SaveAs(x.Filename);
                });
                TimeAlertSuccess();
            }
            catch (Exception ex)
            {
                AlertOperateFailed("保存", ex); ModelJson = JsonConvert.SerializeObject(model);
            }
        }

        private void LoadData(Guid id)
        {
            var node = bll.DbContext.ProjectNodes.FirstOrDefault(x => x.ID == id);
            if (node == null)
            {
                AlertDataNotFound(); return;
            }
            var datas = from x in bll.DbContext.ProjectNodePoints.Where(x => x.ProjectNodeID == id) select new { ID = x.ID, Name = x.PointItem.Name, Status = x.Status };
            this.repWorkPoint.DataSource = datas.ToList();
            this.repWorkPoint.DataBind();

            var contacts = bll.DbContext.NodePointContactses.Where(w => w.ProjectNodePointItem.ProjectNodeID == id).ToList();
            ContactsJson = JsonConvert.SerializeObject(contacts);

            model = new NodeView();
            model.Node = bll.DbContext.ProjectNodes.FirstOrDefault(x => x.ID == id);
            if (model.Node == null)
            {
                AlertDataNotFound(); return;
            }
            this.hidID.Value = model.Node.ID.ToString();
            this.hidProjectID.Value = model.Node.ProjectID.ToString();
            model.InFiles = new List<NodeInFilesView>();
            bll.DbContext.NodeInFiles.Where(x => x.NodeID == model.Node.ID).ToList().ForEach(w =>
            {
                model.InFiles.Add(new NodeInFilesView
                {
                    NodeID = w.NodeID,
                    ActualDate = w.ActualDate,
                    Completed = w.Completed,
                    Department = w.Department,
                    ExpectDate = w.ExpectDate,
                    FileURI = w.FileURI,
                    ID = w.ID,
                    Name = w.Name,
                });
            });
            model.OutFiles = new List<NodeOutFilesView>();
            bll.DbContext.NodeOutFiles.Where(x => x.NodeID == model.Node.ID).ToList().ForEach(w =>
            {
                model.OutFiles.Add(new NodeOutFilesView
                {
                    NodeID = w.NodeID,
                    ActualDate = w.ActualDate,
                    Completed = w.Completed,
                    FileURI = w.FileURI,
                    ID = w.ID,
                    Name = w.Name,
                });
            });
            model.PointContacts = new List<PointContactsData>();
            bll.DbContext.Contacts.Load();
            bll.DbContext.Points.Load();
            bll.DbContext.ProjectNodePoints.Where(w => w.ProjectNodeID == model.Node.ID).OrderBy(x => x.Order).ToList().ForEach(x =>
            {
                var pcd = new PointContactsData { Point = new NodePointView(x) };
                pcd.Contacts = new List<PointContactsView>();
                bll.DbContext.NodePointContactses.Where(w0 => w0.NodePointID == x.ID).ToList().ForEach(p =>
                {
                    pcd.Contacts.Add(new PointContactsView(p));
                });
                model.PointContacts.Add(pcd);
            });
            ModelJson = JsonConvert.SerializeObject(model);
        }
    }
}